/*
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package utopiaintelpackage.sot;

import java.text.NumberFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import main.CommonMethods;

import org.jibble.pircbot.Colors;

import tools.UtopiaTime;
import utopiaintelpackage.AbstractIntel;
import botobjects.Race;

import commandhandlers.IntelHandler;

/**
 * This class represents a SoT The class offers convenience methods for adding and removing commonly used parameters
 * 
 * 
 */
public class SoT extends AbstractIntel {
   public String getBe() {
	  if (getParameter("be") == null)
		 return "";
	  return (String) getParameter("be");
   }

   public String getDragon() {
	  if (getParameter("dragon") == null)
		 return "";
	  return (String) getParameter("dragon");
   }

   public Integer getDspecs() {
	  if (getParameter("dspecs") == null)
		 return 0;
	  return (Integer) getParameter("dspecs");
   }

   public Integer getElites() {
	  if (getParameter("elites") == null)
		 return 0;
	  return (Integer) getParameter("elites");
   }

   public String getExportLine() {
	  if (getParameter("export") == null)
		 return "";
	  return (String) getParameter("export");
   }

   public Integer getFood() {
	  if (getParameter("food") == null)
		 return 0;
	  return (Integer) getParameter("food");
   }

   public String getHit() {
	  if (getParameter("hit") == null)
		 return "";
	  return (String) getParameter("hit");
   }

   public Integer getHorses() {
	  if (getParameter("horses") == null)
		 return 0;
	  return (Integer) getParameter("horses");
   }

   public Boolean getInfiltrated() {
	  if (getParameter("infiltrated") == null)
		 return false;
	  return (Boolean) getParameter("infiltrated");
   }

   public long getInfiltratedTime() {
	  if (getParameter("infiltratedtime") == null)
		 return 0L;
	  return (Long) getParameter("infiltratedtime");
   }

   @Override
   public List<String> getIRCOutput(final boolean shortVersion) {
	  List<String> out = new LinkedList<String>();
	  Double nwpa = getNw() * 1.0 / getLand();
	  Double tpa = getThieves() * 1.0 / getLand();
	  Double wpa = getWizards() * 1.0 / getLand();
	  Double opa = getMo() * 1.0 / getLand();
	  Double dpa = getMd() * 1.0 / getLand();

	  NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
	  nf.setGroupingUsed(false);
	  nf.setMaximumFractionDigits(2);
	  nf.setMinimumFractionDigits(0);

	  Race race = Race.getRace(getRace());
	  if (race == null)
		 return out;
	  int tw = 0;
	  if (getRace().equals("Halfling") || getRace().equals("Avian") || getRace().equals("Faery")|| getRace().equals("Undead")) {
		 tw = getPeasants() / 4;
	  }
	  Double ome = getMo()
			* 1.0
			/ (getOspecs() * race.getOspecstr() + getElites() * race.getEliteostr() + getSoldiers()*(getRace().equals("Halfling")?2:1)
				  + Math.min(getOspecs() + getElites() + getSoldiers(), getHorses()) + Math.min(
				  (getOspecs() + getElites() + getSoldiers()) / 5, getPrisoners()) * 3);
	  Double dme = getMd() * 1.0 / (getDspecs() * race.getDspecstr() + getElites() * race.getElitedstr() + getSoldiers()*(getRace().equals("Halfling")?2:1) + tw);
	  Double pmo = (getOspecs() * race.getOspecstr() + getElites() * race.getEliteostr() * race.getElitesoutratio() / 100.0
			+ getSoldiers()*(getRace().equals("Halfling")?2:1) + Math.min(getOspecs() + getElites() + getSoldiers(), getHorses()) + Math.min((getOspecs()
			+ getElites() + getSoldiers()) / 5, getPrisoners()) * 3)
			* ome;
	  Double pmd = (getDspecs() * race.getDspecstr() + getElites() * race.getElitedstr() * (1 - race.getElitesoutratio() / 100.0)
			+ getSoldiers()*(getRace().equals("Halfling")?2:1) + tw)
			* dme;

	  String adderPers = CommonMethods.getPersonality(getSavedBy());
	  out.add(">> " + Colors.OLIVE + getName() + getKdloc() + Colors.NORMAL + " << " + Colors.OLIVE + getRace() + " "
			+ getPersonality() + Colors.NORMAL
			+ (adderPers.equals("Tactician") ? Colors.BOLD + " Tactician-" + Colors.NORMAL : " ") + "SoT added: "
			+ UtopiaTime.compareTimes(getUpdated().getTime()) + " ago"
			+ ("".equals(getSavedBy()) ? "" : " by " + Colors.NORMAL + "o" + Colors.RED + getSavedBy() + Colors.NORMAL + "o"));

	  if (shortVersion) {
		 out.add("Export:" + Colors.DARK_GREEN + " " + getExportLine());
	  } else {
		 out.add("Land: " + Colors.PURPLE + getLand() + Colors.NORMAL + " NW: " + Colors.PURPLE + getNw() + Colors.NORMAL
			   + " NWPA: " + Colors.PURPLE + nf.format(nwpa) + Colors.NORMAL + " BE: " + Colors.PURPLE + getBe() + Colors.NORMAL
			   + " Peasants: " + Colors.PURPLE + getPeasants() + Colors.NORMAL + " TB: " + Colors.PURPLE + getTradeBalance());
		 out.add("Gold: " + Colors.BLUE + getMoney() + Colors.NORMAL + " Food: " + Colors.BLUE + getFood() + Colors.NORMAL
			   + " Runes: " + Colors.BLUE + getRunes() + Colors.NORMAL + " TPA: " + IntelHandler.colorIntel(getInfiltratedTime())
			   + (tpa < 0 ? "?" : nf.format(tpa)) + Colors.NORMAL + " WPA: " + Colors.GREEN + (wpa < 0 ? "?" : nf.format(wpa)));
		 out.add("Solds: " + Colors.MAGENTA + getSoldiers() + Colors.NORMAL + " Ospecs: " + Colors.MAGENTA + getOspecs()
			   + Colors.NORMAL + " Dspecs: " + Colors.MAGENTA + getDspecs() + Colors.NORMAL + " Elites: " + Colors.MAGENTA
			   + getElites() + Colors.NORMAL + " Horses: " + Colors.MAGENTA + getHorses() + Colors.NORMAL + " Prisoners: "
			   + Colors.MAGENTA + getPrisoners());
		 out.add("OME: " + Colors.PURPLE + nf.format(ome) + Colors.NORMAL + " Offense: " + Colors.RED + getMo() + " ("
			   + nf.format(opa) + " opa)" + Colors.NORMAL + " DME: " + Colors.PURPLE + nf.format(dme) + Colors.NORMAL
			   + " Defense: " + Colors.RED + getMd() + " (" + nf.format(dpa) + " dpa)");
		 out.add("Practical Off: " + Colors.BLUE + nf.format(pmo.intValue()) + " (" + nf.format(pmo / getLand()) + " opa)"
			   + Colors.NORMAL + " Practical Def: " + Colors.BLUE + nf.format(pmd.intValue()) + " (" + nf.format(pmd / getLand())
			   + " dpa)");

		 boolean plagued = getPlague();
		 String hit = getHit();
		 String dragon = getDragon().trim();
		 String info = ("".equals(hit) ? "" : hit + " ") + ("".equals(dragon) ? "" : "Has a " + dragon + ". ")
			   + (plagued ? "Has the Plague." : "");
		 if (!"".equals(info)) {
			out.add(Colors.RED + info);
		 }

		 if (!getExportLine().equals("")) {
			out.add("Export:" + Colors.DARK_GREEN + " " + getExportLine());
		 }
	  }
	  return out;
   }

   public String getKdloc() {
	  if (getParameter("kdloc") == null)
		 return "";
	  return (String) getParameter("kdloc");
   }

   public Integer getLand() {
	  if (getParameter("land") == null)
		 return 0;
	  return (Integer) getParameter("land");
   }

   public Integer getMd() {
	  if (getParameter("md") == null)
		 return 0;
	  return (Integer) getParameter("md");
   }

   public Integer getMo() {
	  if (getParameter("mo") == null)
		 return 0;
	  return (Integer) getParameter("mo");
   }

   public Integer getMoney() {
	  if (getParameter("money") == null)
		 return 0;
	  return (Integer) getParameter("money");
   }

   public String getName() {
	  if (getParameter("name") == null)
		 return "";
	  return (String) getParameter("name");
   }

   public Integer getNw() {
	  if (getParameter("nw") == null)
		 return 0;
	  return (Integer) getParameter("nw");
   }

   public Integer getOspecs() {
	  if (getParameter("ospecs") == null)
		 return 0;
	  return (Integer) getParameter("ospecs");
   }

   public Integer getPeasants() {
	  if (getParameter("peasants") == null)
		 return 0;
	  return (Integer) getParameter("peasants");
   }

   public String getPersonality() {
	  if (getParameter("personality") == null)
		 return "";
	  return (String) getParameter("personality");
   }

   public Boolean getPlague() {
	  if (getParameter("plague") == null)
		 return false;
	  return (Boolean) getParameter("plague");
   }

   public Integer getPrisoners() {
	  if (getParameter("prisoners") == null)
		 return 0;
	  return (Integer) getParameter("prisoners");
   }

   public String getRace() {
	  if (getParameter("race") == null)
		 return "";
	  return (String) getParameter("race");
   }

   @Override
   public Map<String, Object> getRPCOutput(final int... args) {
	  Map<String, Object> out = new HashMap<String, Object>();
	  out.put("Name", getName());
	  out.put("KD", getKdloc());
	  out.put("Race", getRace());
	  out.put("Personality", getPersonality());
	  out.put("Title", getTitle());
	  out.put("Ruler Name", getRulerName());
	  out.put("Trade Balance", getTradeBalance());
	  out.put("BE", getBe());
	  out.put("Soldiers", getSoldiers());
	  out.put("Off Specs", getOspecs());
	  out.put("Def Specs", getDspecs());
	  out.put("Elites", getElites());
	  out.put("Horses", getHorses());
	  out.put("Prisoners", getPrisoners());
	  out.put("MO", getMo());
	  out.put("MD", getMd());
	  out.put("Hit", getHit());
	  out.put("Plague", getPlague());
	  out.put("Dragon", getDragon());
	  out.put("Wizards", getWizards());
	  out.put("Thieves", getThieves());
	  out.put("Infiltrated", getInfiltrated());
	  out.put("Infiltrated Time", new Date(getInfiltratedTime()));
	  out.put("Gold", getMoney());
	  out.put("Food", getFood());
	  out.put("Runes", getRunes());
	  out.put("Peasants", getPeasants());
	  out.put("Export Line", getExportLine());
	  out.put("Saved By", getSavedBy());
	  out.put("Added Time", getUpdated());
	  return out;
   }

   public String getRulerName() {
	  if (getParameter("rulername") == null)
		 return "";
	  return (String) getParameter("rulername");
   }

   public Integer getRunes() {
	  if (getParameter("runes") == null)
		 return 0;
	  return (Integer) getParameter("runes");
   }

   public String getSavedBy() {
	  if (getParameter("savedby") == null)
		 return "";
	  return (String) getParameter("savedby");
   }

   public Integer getSoldiers() {
	  if (getParameter("soldiers") == null)
		 return 0;
	  return (Integer) getParameter("soldiers");
   }

   public Integer getThieves() {
	  if (getParameter("thieves") == null)
		 return 0;
	  return (Integer) getParameter("thieves");
   }

   public String getTitle() {
	  if (getParameter("title") == null)
		 return "";
	  return (String) getParameter("title");
   }

   public Integer getTradeBalance() {
	  if (getParameter("tradebalance") == null)
		 return 0;
	  return (Integer) getParameter("tradebalance");
   }

   @Override
   public String getTypeOfIntel() {
	  return "SoT";
   }

   public Date getUpdated() {
	  return (Date) getParameter("updated");
   }

   public Integer getWizards() {
	  if (getParameter("wizards") == null)
		 return 0;
	  return (Integer) getParameter("wizards");
   }

   @Override
   public boolean isComplete() {
	  return getParameter("name") != null && getParameter("kdloc") != null && getParameter("title") != null
			&& getParameter("race") != null && getParameter("personality") != null && getParameter("rulername") != null
			&& getParameter("land") != null && getParameter("money") != null && getParameter("food") != null
			&& getParameter("runes") != null && getParameter("peasants") != null && getParameter("be") != null
			&& getParameter("soldiers") != null && getParameter("ospecs") != null && getParameter("dspecs") != null
			&& getParameter("elites") != null && getParameter("horses") != null && getParameter("prisoners") != null
			&& getParameter("mo") != null && getParameter("md") != null && getParameter("tradebalance") != null
			&& getParameter("updated") != null;
   }

   public void setBe(final String be) {
	  setParameter("be", be);
   }

   public void setDragon(final String dragon) {
	  setParameter("dragon", dragon);
   }

   public void setDspecs(final int dspecs) {
	  setParameter("dspecs", dspecs);
   }

   public void setElites(final int elites) {
	  setParameter("elites", elites);
   }

   public void setExportLine(final String export) {
	  setParameter("export", export);
   }

   public void setFood(final int food) {
	  setParameter("food", food);
   }

   public void setHit(final String hit) {
	  setParameter("hit", hit);
   }

   public void setHorses(final int horses) {
	  setParameter("horses", horses);
   }

   public void setInfiltrated(final boolean infiltrated) {
	  setParameter("infiltrated", infiltrated);
   }

   public void setInfiltratedTime(final long infiltratedtime) {
	  setParameter("infiltratedtime", infiltratedtime);
   }

   public void setKdloc(final String kdloc) {
	  setParameter("kdloc", kdloc);
   }

   public void setLand(final int land) {
	  setParameter("land", land);
   }

   public void setMd(final int md) {
	  setParameter("md", md);
   }

   public void setMo(final int mo) {
	  setParameter("mo", mo);
   }

   public void setMoney(final int money) {
	  setParameter("money", money);
   }

   public void setName(final String name) {
	  setParameter("name", name);
   }

   public void setNw(final int nw) {
	  setParameter("nw", nw);
   }

   public void setOspecs(final int ospecs) {
	  setParameter("ospecs", ospecs);
   }

   public void setPeasants(final int peasants) {
	  setParameter("peasants", peasants);
   }

   public void setPersonality(final String personality) {
	  setParameter("personality", personality);
   }

   public void setPlague(final boolean b) {
	  setParameter("plague", b);
   }

   public void setPrisoners(final int prisoners) {
	  setParameter("prisoners", prisoners);
   }

   public void setRace(final String race) {
	  setParameter("race", race);
   }

   public void setRulerName(final String rulerName) {
	  setParameter("rulername", rulerName);
   }

   public void setRunes(final int runes) {
	  setParameter("runes", runes);
   }

   public void setSavedBy(final String savedBy) {
	  setParameter("savedby", savedBy);
   }

   public void setSoldiers(final int soldiers) {
	  setParameter("soldiers", soldiers);
   }

   public void setThieves(final int thieves) {
	  setParameter("thieves", thieves);
   }

   public void setTitle(final String title) {
	  setParameter("title", title);
   }

   public void setTradeBalance(final int tradeBalance) {
	  setParameter("tradebalance", tradeBalance);
   }

   public void setUpdated(final Date updated) {
	  setParameter("updated", updated);
   }

   public void setWizards(final int wizards) {
	  setParameter("wizards", wizards);
   }
}
